﻿#pragma once

#include "MapObject.h"
#include "../../Shared/Enums.h"
#include "PlayerObject.h"
#include "DelayedAction.h"
#include "MonsterObject.h"
#include "../../Shared/Packet.h"
#include <string>
#include <algorithm>
#include "exceptionhelper.h"

using namespace Server::MirEnvir;
namespace S = ServerPackets;

namespace Server::MirObjects
{
    class SpellObject : public MapObject
    {
    private:
        std::string Name;
        int CurrentMapIndex = 0;
        Point *CurrentLocation;
        MirDirection Direction = static_cast<MirDirection>(0);
        unsigned short Level = 0;

    public:
        virtual ~SpellObject()
        {
            delete Caster;
            delete CastLocation;
        }

        ObjectType getRace() const override;

        std::string getName() const override;
        void setName(const std::string &value) override;
        int getCurrentMapIndex() const override;
        void setCurrentMapIndex(int value) override;
        Point *getCurrentLocation() const override;
        void setCurrentLocation(Point *value) override;
        MirDirection getDirection() const override;
        void setDirection(MirDirection value) override;
        unsigned short getLevel() const override;
        void setLevel(unsigned short value) override;
        bool getBlocking() const override;

        long long TickTime = 0, StartTime = 0;
        PlayerObject *Caster;
        int Value = 0, TickSpeed = 0;
        Spell Spell = static_cast<Spell>(0);
        Point *CastLocation;
        bool Show = false, Decoration = false;

        //ExplosiveTrap
        int ExplosiveTrapID = 0;
        int ExplosiveTrapCount = 0;
        bool DetonatedTrap = false;

        int getHealth() const override;
        int getMaxHealth() const override;


        void Process() override;
        void ProcessSpell(MapObject *ob);

        void DetonateTrapNow();

        void SetOperateTime() override;

        void Process(DelayedAction *action) override;
        bool IsAttackTarget(PlayerObject *attacker) override;
        bool IsAttackTarget(MonsterObject *attacker) override;
        int Attacked(PlayerObject *attacker, int damage, DefenceType type = DefenceType::ACAgility, bool damageWeapon = true) override;
        int Attacked(MonsterObject *attacker, int damage, DefenceType type = DefenceType::ACAgility) override;

        int Struck(int damage, DefenceType type = DefenceType::ACAgility) override;
        bool IsFriendlyTarget(PlayerObject *ally) override;
        bool IsFriendlyTarget(MonsterObject *ally) override;
        void ReceiveChat(const std::string &text, ChatType type) override;

        Packet *GetInfo() override;

        void ApplyPoison(Poison *p, MapObject *Caster = nullptr, bool NoResist = false, bool ignoreDefence = true) override;
        void Die() override;
        int Pushed(MapObject *pusher, MirDirection dir, int distance) override;
        void SendHealth(PlayerObject *player) override;

        void Spawned() override;

        void Despawn() override;

        void BroadcastInfo() override;
    };
}
